#ifndef _MATHEMATICS_ALGEBRA_MATH_HELPER_
#define _MATHEMATICS_ALGEBRA_MATH_HELPER_

#include "set.h"

#include <vector>
#include <algorithm>
#include <stdexcept>

namespace science
{
	namespace mathematics
	{
		namespace algebra
		{
			class math_helper
			{
			public:
				static int gcf(int num1, int num2)
				{
					auto numerator_factors = find_prime_factors(num1);
					auto denomerator_factors = find_prime_factors(num2);
					int result = 1;
					for (auto& v : numerator_factors)
					{
						unsigned int found = denomerator_factors.find_element(v);
						if (found != -1)
						{
							result *= v;
							denomerator_factors.remove_at(found);
						}
					}
					return result;
				}

				static int lcm(int num1, int num2)
				{
					set<int> num1_multipliers;
					set<int> num2_multipliers;

					int index = 0;
					set<int> intersect = set<int>::set_intersect(num1_multipliers, num2_multipliers);
					while (intersect.size() == 0)
					{
						num1_multipliers.add_element(num1 + num1 * index);
						num2_multipliers.add_element(num2 + num2 * index);
						intersect = set<int>::set_intersect(num1_multipliers, num2_multipliers);
						index++;
					}
					return intersect.get_elemenet(0);
				}

				static set<int> find_prime_factors(int num)
				{
					set<int> factors;
					while (abs(num) != 1)
					{
						int divisor = 2;
						while (num % divisor != 0 && divisor < abs(num))
							divisor++;
						num = num / divisor;
						factors.add_element(divisor);
					}
					return factors;
				}

				static int double_check(double d1, double d2)
				{
					if (abs(d1 - d2) < DBL_EPSILON)
						return 0;
					return d1 > d2 ? 1 : -1;
				}
			};
		}
	}
}

#endif